package net.sunofbeach.blog.controller.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sunofbeach.blog.pojo.Category;
import net.sunofbeach.blog.pojo.User;
import net.sunofbeach.blog.response.Result;
import net.sunofbeach.blog.response.ResultEnum;
import net.sunofbeach.blog.service.CategoryService;
import net.sunofbeach.blog.service.UserService;
import net.sunofbeach.blog.utils.Constants;
import net.sunofbeach.blog.utils.TextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Bing
 * @since 2021-12-01
 */
@Api(tags = "分类管理")
@RestController
@RequestMapping("/admin/category")
public class CategoryAdminApi {

    @Resource
    private CategoryService categoryService;

    @Resource
    private UserService userService;

    /**
     * 添加分类
     *
     * @param category
     * @return
     * @PreAuthorize("@permission.admin()") 管理员权限,
     * 用会报错 org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported
     */
    @ApiOperation("新增分类")
    @PostMapping
    public Result addCategory(@RequestBody Category category) {
        // 检验当前操作用户的身份
        User currentUser = userService.checkSobUser();
        if (currentUser == null) {
            // 账号未登录
            return Result.build(null, ResultEnum.ACCOUNT_NOT_LOGIN);
        }
        // 判断角色，拥有 role_admin 角色可以操作
        if (!Constants.User.ROLE_ADMIN.equals(currentUser.getRole())) {
            // 权限不足
            return Result.build(null, ResultEnum.PERMISSION_DENIED);
        }
        // 检查数据
        // 必须要有的数据：分类名称、分类的 pinyin、顺序、描述
        if (TextUtils.isEmpty(category.getName())) {
            return Result.fail().message("分类名称不能为空");
        }
        if (TextUtils.isEmpty(category.getPinyin())) {
            return Result.fail().message("分类拼音不能为空");
        }
        if (TextUtils.isEmpty(category.getDescription())) {
            return Result.fail().message("分类描述不可以为空");
        }
        // 补全数据（因在数据库里设置了默认值，这里无须补全数据）
        // 保存数据
        categoryService.save(category);
        // 返回结果
        return Result.ok().message("新增分类成功");
    }

    /**
     * 根据ID查询分类
     * 使用 case : 修改的时候，获取一下，填充弹窗
     * 不获取也可以，从列表里获取数据
     * 需要权限：管理员权限
     *
     * @param categoryId
     * @return
     */
    @ApiOperation("根据ID查询分类")
    @PreAuthorize("@permission.admin()")
    @GetMapping("/{categoryId}")
    public Result getCategory(@PathVariable("categoryId") String categoryId) {
        if (StringUtils.isEmpty(categoryId)) {
            return null;
        }
        Category category = categoryService.getById(categoryId);
        return Result.ok(category);
    }


    /**
     * 获取分类列表
     *
     * @return
     */
    @ApiOperation("获取分类列表数据")
    @GetMapping("/list")
    public Result search() {
        // 判断角色
        User user = userService.checkSobUser();
        // 普通用户、未登录用户，只能获取正常的 category
        if (user == null || !Constants.User.ROLE_ADMIN.equals(user.getRole())) {
            // 只能获取正常状态的分类，注意排序先状态后时间
            List<Category> list = categoryService.list(new LambdaQueryWrapper<Category>()
                    .eq(Category::getStatus, Constants.Status.NORMAL)
                    .orderByDesc(Category::getStatus)
                    .orderByDesc(Category::getCreateTime));
            return Result.ok(list);

        } else {
            // 管理员，获取所有分类信息，注意排序先状态后时间
            List<Category> list = categoryService.list(new LambdaQueryWrapper<Category>()
                    .orderByDesc(Category::getStatus)
                    .orderByDesc(Category::getCreateTime));
            return Result.ok(list);
        }
    }


    @ApiOperation("更新分类")
    @PutMapping
    public Result updateCategory(@RequestBody Category category) {
        // 检验当前操作用户的身份
        User currentUser = userService.checkSobUser();
        if (currentUser == null) {
            // 账号未登录
            return Result.build(null, ResultEnum.ACCOUNT_NOT_LOGIN);
        }
        // 判断角色，拥有 role_admin 角色可以操作
        if (!Constants.User.ROLE_ADMIN.equals(currentUser.getRole())) {
            // 权限不足
            return Result.build(null, ResultEnum.PERMISSION_DENIED);
        }
        // 空判断
        if (StringUtils.isEmpty(category.getId())) {
            return Result.fail().message("分类ID不能为空");
        }
        if (StringUtils.isEmpty(category.getName())) {
            return Result.fail().message("分类名不能为空");
        }
        if (StringUtils.isEmpty(category.getPinyin())) {
            return Result.fail().message("分类拼音不能为空");
        }
        if (StringUtils.isEmpty(category.getDescription())) {
            return Result.fail().message("分类描述不能为空");
        }
        // 保存数据
        categoryService.updateById(category);
        // 返回结果
        return Result.ok().message("修改分类成功");
    }


    @ApiOperation("逻辑删除分类")
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    @DeleteMapping("/{categoryId}")
    public Result deleteCategory(@PathVariable("categoryId") String categoryId) {

        // 检验当前操作用户的身份
        User currentUser = userService.checkSobUser();
        if (currentUser == null) {
            // 账号未登录
            return Result.build(null, ResultEnum.ACCOUNT_NOT_LOGIN);
        }
        // 判断角色，拥有 role_admin 角色可以操作
        if (!Constants.User.ROLE_ADMIN.equals(currentUser.getRole())) {
            // 权限不足
            return Result.build(null, ResultEnum.PERMISSION_DENIED);
        }

        if (StringUtils.isEmpty(categoryId)) {
            return Result.fail().message("分类ID不能为空");
        }
        // 查出数据库分类
        Category category = categoryService.getById(categoryId);

        // 修改状态为 0 表示删除
        category.setStatus(Constants.Status.DELETE);
        category.setUpdateTime(LocalDateTime.now());
        // 保存
        categoryService.updateById(category);
        return Result.ok().message("删除分类成功");
    }


}
